package com.vtuzx.kingdee.xqc_core.utils;

import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxHttpUtil;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.constant.IJikeyunConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;

public class JiKeYunUtil {

    /** Logger */
    private static final Logger _logger = LoggerFactory.getLogger(JiKeYunUtil.class);

    /**
     * 执行API
     *
     * @param isProd 应用类型
     * @param appKey appkey
     * @param appSecret 秘钥
     * @param method API方法
     * @param param 入参
     * @return 执行结果
     * @throws Exception 异常
     */
    public static VtuzxMap callApi(boolean isProd, long appKey, String appSecret, String method, Map<String, Object> param, boolean isBatch) throws Exception {
        return callApi(isProd, appKey, appSecret, method, param, 3, isBatch);
    }

    /**
     * 执行API
     *
     * @param isProd 是否生产
     * @param appKey 接口账号
     * @param appSecret 接口密钥
     * @param method API方法
     * @param param 入参
     * @param retry 重试次数
     * @return 执行结果
     * @throws Exception 异常
     */
    public static VtuzxMap callApi(boolean isProd, long appKey, String appSecret, String method, Map<String, Object> param, int retry, boolean isBatch) throws Exception {
        String contenttype = "json";
        String version = "v1.0";
        String timestamp = VtuzxUtil.formatYmdHmsF(new Date());
        String paramStr = VtuzxUtil.json2Str(param);

        VtuzxMap signMap = new VtuzxMap();
        signMap.append("appkey", appKey);
        if (isBatch) {
            signMap.append("bizcontent",  "[" + paramStr + "]");
        } else {
            signMap.append("bizcontent", paramStr);
        }
        signMap.append("contenttype", contenttype);
        signMap.append("method", method);
        signMap.append("timestamp", timestamp);
        signMap.append("version", version);
        List<String> arr = new ArrayList<>(signMap.keySet());
        Collections.sort(arr);
        StringBuilder content = new StringBuilder(appSecret);
        for (String s : arr) {
            content.append(s).append(signMap.get(s));
        }
        content.append(appSecret);
        System.out.println(content);
        String sign = content.toString().toLowerCase();
        sign = VtuzxUtil.md5(sign);
        signMap.append("sign", sign);

        StringBuilder paramBuilder = new StringBuilder();
        List<String> paramKeys = new ArrayList<>(signMap.keySet());
        for (String key : paramKeys) {
            if (paramBuilder.length() > 0) {
                paramBuilder.append("&");
            }
//            List<String> bizcontentList = new ArrayList<>();
            if ("bizcontent".equals(key)) {
//                bizcontentList.add(VtuzxUtil.getString(signMap, key));
                paramBuilder.append(key).append("=").append(URLEncoder.encode(VtuzxUtil.getString(signMap, key), "UTF-8"));
            } else {
            paramBuilder.append(key).append("=").append(VtuzxUtil.getString(signMap, key));
            }
        }
        VtuzxMap res = null;
        try {
            String baseUrl = "https://open.jackyun.com/open/openapi/do";
            _logger.info("jikeyun callApi url:" + baseUrl);
            _logger.info("jikeyun callApi param:" + param);
            String resStr = VtuzxHttpUtil.post(baseUrl, paramBuilder.toString());
            res = VtuzxUtil.str2Json(resStr);
        } catch(Exception e) {
            if (retry == 0) {
                throw e;
            }
            return callApi(isProd, appKey, appSecret, method, param, retry - 1, isBatch);
        }
        String code = VtuzxUtil.getString(res, "code");
        if ("200".equals(code)) {
            return res;
        }
        throw new VtuzxException(VtuzxUtil.getString(res, "msg"));
    }

    /**
     * 执行API
     *
     * @param isProd 应用类型
     * @param appKey 应用ID
     * @param appSecret 应用秘钥
     * @param method API方法
     * @param param 入参
     * @return 执行结果
     * @throws Exception 异常
     */
    public static VtuzxMap getTokenApi(boolean isProd, String appKey, String appSecret, String method, Map<String, Object> param) throws Exception {
        return callCodeApi(isProd, appKey, appSecret, method, param, 3);
    }

    /**
     * 获取授权码API
     *
     * @param isProd 是否生产
     * @param appKey 店铺KEY
     * @param appSecret 店铺秘钥
     * @param method 方法
     * @param param 参数
     * @param retry 重试次数
     * @return 执行结果
     * @throws Exception 异常
     */
    public static VtuzxMap callCodeApi(boolean isProd, String appKey, String appSecret, String method, Map<String, Object> param, int retry) throws Exception {
        Map<String, Object> calcMap = param == null? new HashMap<>(): new HashMap<>(param);
        calcMap.put("appkey", appKey);
        calcMap.put("appsecret", appSecret);
        String timestamp = VtuzxUtil.formatYmdHmsF(new Date());
        VtuzxMap res = null;
        try {
            String baseUrl = String.format("%s?method=%s&timestamp=%s&format=json&app_key=%s&v=1.0&sign_method=md5",
                    isProd? IJikeyunConst.API_URL: IJikeyunConst.API_URL_DEV, method, timestamp, appKey);
            res = VtuzxHttpUtil.json(baseUrl, calcMap);
        } catch(Exception e) {
            if (retry == 0) throw e;
            return callCodeApi(isProd, appKey, appSecret, method, param, retry - 1);
        }
        String code = VtuzxUtil.getString(res, "code");
        if ("0".equals(code)) {
            return res;
        }
        if (retry == 0 || !("-9999".equals(code))) {
            throw new VtuzxException(code + ":" + VtuzxUtil.getString(res, "message"));
        }
        return callCodeApi(isProd, appKey, appSecret, method, param, retry - 1);
    }
}
